﻿using ACC.Business;
using ACC.Business.Process;
using ACC.Business.Stn;
using ACC.Data;
using ACC.Data.ACCLog;
using ACC.Data.Comm;
using ACC.Data.Entities.Mes;
using ACC.Data.Line;
using ACC.Device;
using ACC.LineDevice.KukaPack;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Script
{
    /// <summary>
    /// 贴FPC, 人工
    /// 三个FPC分左中右，通过ItemPartNo区分 （MES下发的BOM里三个FPC是三个不同的BOMItem）
    /// 要求是客户端人工扫描的时候，扫一个码检查一次，可能做不到，只能客户端按照扫的顺序Load发过来，判断顺序
    /// </summary>
    public class L1P06010 : StnProcessKukaClientWithPLC
    {
        int Days = 7; // 电芯批次不能合批条件，7天内不同批
        string[] ScannedBarcode = new string[3];
        DictionaryEx<string, string[]> TypeMapping = new DictionaryEx<string, string[]>();

        public L1P06010(StnRunningData data)
            : base(data)
        {
            // 1:左模组、2:中模组,3:右模组， 模组条码第9位
            PlcName = "PLC150";
            // 按照左中右的顺序初始化数组
            TypeMapping.Add("2111-00062", new string[] { "2134-00008", "2134-00007", "2134-00006" });
            TypeMapping.Add("2111-00078", new string[] { "2134-00046", "2134-00045", "2134-00044" });
            TypeMapping.Add("2111-00079", new string[] { "2134-00043", "2134-00042", "2134-00041" });
            TypeMapping.Add("2111-00080", new string[] { "2134-00052", "2134-00051", "2134-00050" });
            TypeMapping.Add("2111-00081", new string[] { "2134-00055", "2134-00054", "2134-00053" });
            TypeMapping.Add("2111-00087", new string[] { "2134-00093", "2134-00092", "2134-00091" });
            TypeMapping.Add("2111-00088", new string[] { "2134-00097", "2134-00096", "2134-00095" });
            TypeMapping.Add("2111-00111", new string[] { "2134-00220", "2134-00221", "2134-00222" });
            TypeMapping.Add("2111-00113", new string[] { "2134-00191", "2134-00192", "2134-00193" });
        }

        protected override ACCDevice CreateDevice()
        {
            ACCDevice dev = base.CreateDevice();
            if (kukaSiemensDev != null)
            {
                kukaSiemensDev.DB190 = 800;
                kukaSiemensDev.DB190_Offset = 14000;
                kukaSiemensDev.DB192 = 80;
                kukaSiemensDev.DB192_PLC_Offset = 14066;

                kukaSiemensDev.DB193 = 800;
                kukaSiemensDev.DB193_PLC_Offset = 14034;
                kukaSiemensDev.DB193_ACC_Offset = 14068;
                kukaSiemensDev.DB194 = 800;
                kukaSiemensDev.DB194_PLC_Offset = 14034;
                kukaSiemensDev.DB194_PLC_Data_Offset = 14078;

                kukaSiemensDev.BarcodeLength = 30;
                kukaSiemensDev.LoadBarcodeCount = 4;
                kukaSiemensDev.UnloadBarcodeCount = 4;
            }

            return dev;
        }

        public override ACCCode ReadLoadParam(ACCDevice dev, out ACCDevice.LoadParam param)
        {
            //partno.BomCfg.GetBomItemCfgByIDName("FPC").Clone()
            ACCCode rs = base.ReadLoadParam(dev, out param);
            if (rs == ACCCode.ACCOK && param.ComponentSN.Length > 2 && _data.PartNo != null)
            {
                // 根据Pack的PartNo物料号来匹配扫描的FPC码（分左中右）
                var type = TypeMapping[_data.PartNo.BomCfg.PartNo];
                if (type == null)
                {
                    rs = ACCCode.UserDef_131; // 型号未配置FPC码左中右关系
                    EventLog.LogStation(_data, StnLog.LogType.Error,
                        string.Format("{0}型号未配置FPC左中右对应关系", _data.PartNo.BomCfg.PartNo));
                }
                else
                {
                    for (int index = 0; index < 3; ++index)
                    {
                        if (!param.ComponentSN[index].StartsWith(type[index].Replace("-", "")))
                        {
                            rs = ACCCode.UserDef_124; // FPC码顺序不对

                            EventLog.LogStation(_data, StnLog.LogType.Error,
                                string.Format("第{0}个条码扫描顺序不对，扫描的条码是{1}", index, param.ComponentSN[index]));
                            break;
                        }
                    }
                }
            }

            return rs;
        }

        public override ACCCode SendLoadResult(ACCDevice dev, ACCDevice.LoadResult result)
        {
            if(result.ErrorCode == ACCCode.ACCOK)
            {
                // 获取Pack电池包对应的三个模组的电芯批次，并比较是否可以合批（规则是7天内的电芯批次可以合批），若批次为空也报警
                // 同时检查电芯数量 （规则是三个模组BOM里定义的电芯数量和实际绑定的电芯数量进行比较）？（TO-DO: 是否做？）
                WIPUnit unit = UnitDataProcess.GetWIPUnit(_lineData, _unloadProcess._unloadParam.UnitSN);
                if (unit != null)
                {
                    LineData mzLineData = LineManager.LineDatas["PL02_MZ"];
                    LineData jtLineData = LineManager.LineDatas["PL02_JT"];
                    var models = unit.GetUnitIDsByIDName("模组");
                    List<string> lots = new List<string>(); // 每个模组电芯的批次（同一模组的电芯批次一样）
                    List<DateTime> lotDts = new List<DateTime>();
                    int cellCnt = 0; // 模组绑定的电芯数量
                    int cfgCnt = 0; // BOM配置里的电芯数量
                    foreach (WIPUnitID model in models)
                    {
                        var mzUnit = UnitDataProcess.GetWIPUnit(mzLineData, model.IDValue);
                        if (mzUnit == null) continue;
                        var jtUnitId = mzUnit.GetUnitIDByIDName("模组基体");
                        if (jtUnitId == null) continue;
                        var jtUnit = UnitDataProcess.GetWIPUnit(jtLineData, jtUnitId.IDValue);
                        if (jtUnit == null) continue;

                        var dxUnitIDs = jtUnit.GetUnitIDsByIDName("电芯");
                        if (dxUnitIDs.Length > 0)
                        {
                            string lot = GetBatteryLot(dxUnitIDs[0].IDValue);
                            lots.Add(lot);
                            lotDts.Add(GetLotDateTimeFromBatteryLot(lot));
                            cellCnt += dxUnitIDs.Length;
                            cfgCnt += GetBomItemQty("PL02_JT", "电芯", "L1M03020", jtUnit.PartNo, string.Empty/*dxUnitIDs[0].ItemPartNo*/);
                        }
                        else
                        {
                            lots.Add(string.Empty);
                            lotDts.Add(DateTime.MinValue);
                            result.ErrorCode = ACCCode.UserDef_126; // 电芯批次为空
                            result.ErrorMsg = string.Format("模组{0}的电芯批次为空", model.IDValue);
                        }
                    }

                    if (result.ErrorCode == ACCCode.ACCOK && Days >= 0)
                    {
                        var max = lotDts.Max();
                        var min = lotDts.Min();
                        if ((max - min).Days > Days)
                        {
                            result.ErrorCode = ACCCode.UserDef_127; // 电芯不能合批，电芯批次日期相差超过7天
                            result.ErrorMsg = string.Format("电芯不能合批，电芯批次日期相差超过{0}天", Days);
                        }
                    }

                     if (result.ErrorCode == ACCCode.ACCOK)
                     {
                         if (cfgCnt != cellCnt)
                         {
                             result.ErrorCode = ACCCode.UserDef_128; // 绑定电芯数量和BOM配置的BOM数量不匹配
                             result.ErrorMsg = string.Format("绑定电芯数量{0}和BOM配置的电芯数量{1}不匹配", cellCnt, cfgCnt);
                         }
                     }
                }
            }

            return base.SendLoadResult(dev, result);
        }

        /// <summary>
        /// 根据电芯批次码获取批次日期
        /// </summary>
        /// <param name="lot"></param>
        /// <returns></returns>
        DateTime GetLotDateTimeFromBatteryLot(string lot)
        {
            try
            {
                if (lot.Length > 8)
                {
                    string d = lot.Substring(lot.Length - 8, 4);
                    int year = int.Parse(d.Substring(0, 1));
                    DateTime now = DateTime.Now;
                    if (year > now.Year)
                        year = now.Year - now.Year % 10 - 10 + year;
                    else
                        year = now.Year - now.Year % 10 + year;
                    string month = d.Substring(1, 1);
                    if (month == "J") month = "11";
                    if (month == "Q") month = "12";
                    int day = int.Parse(d.Substring(2, 2));
                    return new DateTime(year, int.Parse(month), day);
                }
            }
            catch { }

            return DateTime.MinValue;
        }

        /// <summary>
        /// MES下发三个BOMItem代表三种FPC，ACC收到MES下发的信息BOM 里自动创建一条3个FPC的虚拟FPC BOMITEM
        /// 这里需要通过FPC条码里包含的物料号信息获取对应的BomItemCfg
        /// </summary>
        /// <param name="stnData"></param>
        /// <returns></returns>
        public override List<SCADAMaterialData> GetMaterialData(StnRunningData stnData)
        {
            var materials = new List<SCADAMaterialData>();
            try
            {
                var opBomCfg = _data.PartNo.BomCfg.BomItemCfg[_data.StnCfg.OPCfg];
                var compSet = stnData.CurrentCompSets[stnData.PartNo.BomCfg.PartNo];
                if (compSet != null)
                {
                    foreach (var comp in compSet.Items)
                    {
                        materials.Add(new SCADAMaterialData()
                        {
                            ctrl_code = string.IsNullOrEmpty(comp.Value.BomItem.IDName) ? (uint)1 : (uint)2, //1-批次件，2-序列件，3-标准件
                            item_code = comp.Value.BomItem.ItemPartNo,
                            item_name = comp.Value.BomItem.Desc,
                            material_unit = "",
                            part_batchsn = comp.Value.LotItem == null ? GetLastLotTrackItem(stnData.StnCfg.LineCfg.Line, stnData.StnCfg.OPCfg.OP, comp.Value.BomItem.ItemPartNo).Lot : comp.Value.LotItem.Lot,
                            part_sn = comp.Value.LotItem == null ? "" : comp.Value.LotItem.Reserved,
                            qty = Convert.ToDecimal(opBomCfg.BomItem[comp.Value.BomItem.ItemPartNo].QtyPer),
                        });
                    }
                }

                List<WIPUnitID> UnitIDs = stnData.LastUnloadUnit.UnitIDs;
                if (UnitIDs != null)
                {
                    foreach (var unitID in UnitIDs)
                    {
                        try
                        {
                            if (unitID.IDValue == stnData.LastUnloadUnit.UnitSN)
                            {
                                continue;
                            }

                            // 通过条码里包含的物料号获取BOM配置
                            var bomItemCfg = opBomCfg == null ? null : opBomCfg.BomItem.Values.FirstOrDefault(c => unitID.IDValue.StartsWith(c.ItemPartNo.Replace("-", "")));
                            
                            materials.Add(new SCADAMaterialData()
                            {
                                ctrl_code = 2, //1-批次件，2-序列件，3-标准件
                                item_code = bomItemCfg == null ? unitID.ItemPartNo : bomItemCfg.ItemPartNo,
                                item_name = bomItemCfg == null ? string.Empty : bomItemCfg.DescLocal,
                                material_unit = bomItemCfg == null ? string.Empty : bomItemCfg.UM,
                                part_batchsn = "",
                                part_sn = unitID.IDValue,
                                qty = 1
                            });
                        }
                        catch (Exception ex)
                        {
                            logger.Error(ex.Message + "\r\n" + ex.StackTrace);
                        }

                    }
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex.Message + "\r\n" + ex.StackTrace);
            }

            return materials;
        }

    }
}